<?php
namespace coser;

class App
{
    //判断是否初始化过
    protected static $init = false;
    //默认命名空间
    public static $namespace = 'app';
    //调度信息
    protected static $dispatch;

    public static function run(Request $request = null)
    {
        //创建request 代理请求
        $request = is_null($request) ? Request::instance() : $request;

        //引入配置文件 绑定路由信息
        $config = self::initCommon();

        $dispatch = self::$dispatch;

        if(empty($dispatch)){
            //解析模块 控制器 操作 参数
            $url = self::parseUrl(Request::path(),$config['config']['pathinfo_depr'],$config['config']['url_route_must']);
            $dispatch = self::dispatch($url);
        }

        //执行
        $data = self::exec($dispatch,$config);

        //输出数据到客户端
        //$type = $request->isAjax() ? $config('default_ajax_return') : $config('default_return_type');
        $type = 'html';
        $response = Response::create($data,$type);

        return $response;
    }

    //初始化配置信息
    public static function initCommon()
    {
        if(empty(self::$init)){
            if(defined('APP_NAMESPACE')){
               self::$namespace = APP_NAMESPACE;
            }

            //添加命名空间
            Loader::addNamespace(self::$namespace,APP_PATH);

            $config = self::init();

            self::$init = true;
        }

        return Config::get();
    }

    //初始化应用
    public static function init()
    {
        //载入公共配置
        $config = Config::load(APP_PATH . 'config' . EXT,'config');

        //载入数据库配置
        Config::load(APP_PATH . 'database' . EXT,'database');

        //载入公共函数库
        if(is_file(APP_PATH . 'common' .EXT))
        {
            include APP_PATH . 'common' . EXT;
        }

        return Config::get();
    }

    //设置调度信息
    public static function dispatch($dispatch, $type = 'module')
    {
        return self::$dispatch = ['type'=>$type,$type=>$dispatch];
    }

    //执行调度
    public static function exec($dispatch, $config)
    {
        switch($dispatch['type']){
            case 'module':
                $data = self::module(
                    $dispatch['module']
                );
                break;
        }

        return $data;
    }

    //执行模块
    public static function module($result)
    {
        $request = Request::instance();

        $moduleName = $result[0];
        $controllerName = $result[1];
        $actionName = $result[2];

        //设置当前请求控制器&操作
        $request->module($moduleName)->controller($controllerName)->action($actionName);

        //实例化控制器
        $instance = Loader::controller($controllerName);

        $call = [$instance,$actionName];

        return self::invokeMethod($call);
    }

    //反射执行类
    public static function invokeMethod($method)
    {
        if(is_array($method)){
            $class   = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]);
            $reflect = new \ReflectionMethod($class, $method[1]);
        }else{
            //静态方法
            $reflect = new \ReflectionMethod($method);
        }

        return $reflect->invokeArgs(isset($class) ? $class : null,[]);
    }

    //反射实例化类
    public static function invokeClass($class,$var = [])
    {
        $reflect     = new \ReflectionClass($class);
        $constructor = $reflect->getConstructor();

        return $reflect->newInstance();
    }

    //解析url
    public static function parseUrl($url,$depr = '/',$autoSearch = false)
    {
        $url =  trim($url,'/');
		
        $item = explode($depr,$url);

        //获取模块
        $module = array_shift($item);
        //获取控制器
        $controller = array_shift($item);
        //获取操作
        $action = array_shift($item);
        //存在参数
        if(false !== strpos($url,'?')){
            $action_item = explode('?',$action);
            //重新获取操作
            $action = array_shift($action_item);
            //获取参数
            $param = array_shift($action_item);
        }

        return [$module,$controller,$action];
    }

}
